//
//  IvoViewPart.m
// Darcy Brockbank, samurai@uriel.cs.mcgill.ca  
// (now samurai@hasc.ca)
//  Adapted from the GlobeSaver module, written by :
//  Ron Blanford, TRW Inc., October 1991.
//

#import "IvoView.h"
#import "Thinker.h"
#import <appkit/NXImage.h>
#import <appkit/Panel.h>
#import <libc.h>
#import <appkit/TextField.h>
#import <math.h>
#import <defaults/defaults.h>
#import <sys/file.h>

@implementation IvoView

- incrementFrame
{
    now = currentTimeInMs();

    if (now > nextRotationTime)
    {
	if (++currentFrame >= numberOfFrames) currentFrame = 0;
	nextRotationTime = now + 1000/framesPerSecond;
    }

    return self;
}

- oneStep
{
    image = [imageList objectAt:currentFrame];
    [self incrementFrame];
    return [super oneStep];
}


static BOOL noAnimFile = FALSE;

#define FRAMES_PER "IvoFramesPerSecond"
#define DEFAULT_FRAMES_PER 14
#define MAX_F 50
#define MIN_F 1

- setup
{
	char buf[1024];
	const char * t;
	appowner = BSThinker();
	sprintf(buf,"%s/IvoView.nib",[appowner moduleDirectory:"Ivo"]);
	[NXApp loadNibFile:buf owner:self withNames:NO];
	[self allocateGState];
	imageList = [[List alloc] init];
	if (t=NXReadDefault([NXApp appName],FRAMES_PER)){
		framesPerSecond = atoi(t);
	} else {
		framesPerSecond = DEFAULT_FRAMES_PER;
	}
	[field setIntValue:framesPerSecond];
	[slider setIntValue:framesPerSecond];
	return self;
}

- writeFramesDefault:sender;
{
	char buf[32];
	sprintf(buf,"%d",framesPerSecond);
	NXWriteDefault([NXApp appName],FRAMES_PER,buf);
	return self;
}

- setFramesPer:sender
{
	
	framesPerSecond = [sender intValue];
	if (framesPerSecond < MIN_F) {
		framesPerSecond = MIN_F;
	} else if (framesPerSecond > MAX_F) {
		framesPerSecond = MAX_F;
	}
	[slider setIntValue:framesPerSecond];
	[field setIntValue:framesPerSecond];
	[self perform:@selector(writeFramesDefault:)
			with:self
			afterDelay:1000
			cancelPrevious:YES];
	return self;
}

- initFrame:(NXRect *)frameRect
{
	char animFrame[1024];
	char buf[1024];
	int i, f;
	id local_image;

	[super initFrame:frameRect];
	[self setup];

	sprintf(buf,"%s/Ivo.anim",[appowner moduleDirectory:"Ivo"]);
	[loadingPanel makeKeyAndOrderFront:self];
	/* construct the image list */
	for (i=0; ; i++) {
		sprintf(animFrame, "%s/Ivo.%d.tiff", buf, i+1);
		if (!(local_image = [NXImage findImageNamed:animFrame]))
		{
		    if ((f=open(animFrame, O_RDONLY)) < 0) break;
			close(f);
//		    printf("Loading %s\n", animFrame);
		    local_image = [[NXImage alloc] initFromFile:animFrame];
		    if (local_image == NULL) break;	// never null, even if no file
		    if ([local_image lockFocus]){
			[local_image unlockFocus];
		    }
		    [local_image setName:animFrame];
		}
		//else printf("Using existing %s\n", animFrame);
		[imageList addObject:local_image];
	}
	[loadingPanel orderOut:self];
	numberOfFrames = i;
	currentFrame = 0;
    
    if (numberOfFrames == 0) {
        if (!noAnimFile)
	    NXRunAlertPanel([NXApp appName], "Could not open %s",
				NULL, NULL, NULL, buf);
	noAnimFile = TRUE;
        return NULL;
    }
    
    [super setImage:[imageList objectAt:0]];
    return self;
}

// override this method so that Thinker can't set the default image.

- setImage:newImage
{
    return self;
}


- (const char *)windowTitle
{
    return "IvoView";
}

- inspector:sender
{
    appowner=sender;
    if (!sharedInspectorPanel){
      [self setup];
    }
    return sharedInspectorPanel;
}

@end
